import uuid
from pathlib import Path

from fastapi import HTTPException, UploadFile
from sqlmodel import Session
from app.schemas.welcome import WelcomeCreate
from app.models.welcome import Welcome

# 配置文件上传设置
UPLOAD_DIR = Path("uploads")
MAX_FILE_SIZE = 1024 * 1024 * 10  # 10MB 文件大小限制
ALLOWED_EXTENSIONS = {"txt", "pdf", "png", "jpg", "jpeg", "gif"}  # 允许的文件类型
# 确保上传目录存在
UPLOAD_DIR.mkdir(exist_ok=True)


def allowed_file(filename: str) -> bool:
    """检查文件扩展名是否允许"""
    return "." in filename and filename.rsplit(".", 1)[1].lower() in ALLOWED_EXTENSIONS


def generate_unique_filename(filename: str) -> str:
    """生成唯一文件名，避免冲突"""
    ext = filename.split(".")[-1]
    unique_id = uuid.uuid4().hex
    return f"{unique_id}.{ext}"


async def create_welcome(session: Session, file: UploadFile) -> Welcome:
    """
    上传单个文件并保存到硬盘
    """
    try:
        # 检查文件类型
        if not allowed_file(file.filename):
            raise HTTPException(
                status_code=400,
                detail=f"不支持的文件类型。允许的类型: {', '.join(ALLOWED_EXTENSIONS)}"
            )

        # 生成唯一文件名
        unique_filename = generate_unique_filename(file.filename)
        file_path = UPLOAD_DIR / unique_filename

        # 保存文件到硬盘
        with open(file_path, "wb") as buffer:
            # 使用分块读取和写入，避免内存溢出
            contents = await file.read()

            # 检查文件大小
            if len(contents) > MAX_FILE_SIZE:
                raise HTTPException(
                    status_code=400,
                    detail=f"文件过大。最大允许: {MAX_FILE_SIZE // (1024 * 1024)}MB"
                )

            buffer.write(contents)
        db_welcome = Welcome(file_path=str(file_path))
        session.add(db_welcome)
        session.commit()
        session.refresh(db_welcome)
        path_dict = {"file_path": "http://localhost:8000/" + db_welcome.file_path}
        db_welcome.sqlmodel_update(path_dict)
        return db_welcome

    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"文件上传失败: {str(e)}")
